package com.shenhaofeng.app.loader.list;

import android.os.Bundle;
import android.os.Looper;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.view.ViewGroup;

import com.shenhaofeng.app.loader.list.internal.LoadSchedulers;
import com.shenhaofeng.app.loader.list.listener.OnBindDataListener;

import java.util.concurrent.Executor;

import rx.Scheduler;


/**
 * Created by Administrator on 2016/8/28.
 */
public abstract class Component<D> {

    private DataSource<D> mDataSource;

    private OnBindDataListener<D> mListener;

    //刷新控件
    private ViewGroup refreshView;

    //数据控件
    private ViewGroup dataView;

    //页面管理器
    private Pager mPager;


    private LoadSchedulers mLoadSchedulers;

    private boolean isAttached = false;



    public Component() {
        this.mLoadSchedulers = new LoadSchedulers();
    }


    public Component(Executor mExecutor) {
        this.mLoadSchedulers = new LoadSchedulers(mExecutor);
    }


    public Component(Looper mLooper) {
        this.mLoadSchedulers = new LoadSchedulers(mLooper);
    }


    /**
     * 设置一个页码管理器管理器
     *
     * @param pageManager
     */
    @CallSuper
    public void setPageManager(Pager pageManager) {
        this.mPager = pageManager;
    }


    /**
     * 获取页码管理器
     *
     * @return
     */
    public Pager getPageManager() {
        return mPager == null ? mPager = new Pager(1, 20) : mPager;
    }


    /**
     * 获取工作线程
     *
     * @return
     */
    protected final Scheduler getWorkScheduler() {
        return mLoadSchedulers.getWorkScheduler();
    }


    protected final ViewGroup getRefreshView() {
        return refreshView;
    }


    protected final ViewGroup getDataView() {
        return dataView;
    }


    public OnBindDataListener<D> getListener() {
        return mListener;
    }


    public DataSource<D> getDataSource() {
        return mDataSource;
    }


    /**
     * 附加View到组件上
     *
     * @param mRefreshLayout
     * @param mDataLayout
     */
    @CallSuper
    protected void attach(@NonNull ViewGroup mRefreshLayout, @NonNull ViewGroup mDataLayout, @NonNull DataSource<D> mDataSource, @NonNull OnBindDataListener<D> listener) {
        if (isAttached) {
            throw new IllegalStateException("只能附加一次");
        }
        isAttached = true;
        this.refreshView = mRefreshLayout;
        this.dataView = mDataLayout;
        this.mDataSource = mDataSource;
        this.mListener = listener;
        if (!hasLoadView(mRefreshLayout, mDataLayout)) {
            throw new IllegalArgumentException("Component不支持当前组件");
        }
    }


    public boolean isAttached() {
        return isAttached;
    }


    /**
     * 该方法为操作做连接，只有符合条件的View才能正常使用Loader
     *
     * @param mRefreshLayout
     * @param mDataLayout
     * @return
     */
    protected abstract boolean hasLoadView(ViewGroup mRefreshLayout, ViewGroup mDataLayout);


    /**
     * 刷新时将会被调用，在该方法内触发数据刷新
     *
     * @param mRefreshLayout
     * @param mDataLayout
     * @param pageSize
     */
    protected abstract void onRefresh(ViewGroup mRefreshLayout, ViewGroup mDataLayout, int page, int pageSize, DataSource<D> dDataSource, OnBindDataListener<D> dataListener);


    /**
     * 数据加载更多时将被调用
     *
     * @param page
     * @param pageSize
     */
    protected abstract void onMore(ViewGroup mRefreshLayout, ViewGroup mDataLayout, int page, int pageSize, DataSource<D> dDataSource, OnBindDataListener<D> dataListener);


    /**
     * 触发刷新
     *
     */
    void refresh() {
        refreshView.post(new Runnable() {
            @Override
            public void run() {
                Pager pager = getPageManager();
                int firstPage = pager.getFirstPage();
                int pageSize = pager.getPageSize();
                onRefresh(refreshView, dataView, firstPage, pageSize, mDataSource, mListener);
            }
        });
    }


    void more(final Bundle args) {
        dataView.post(new Runnable() {
            @Override
            public void run() {
                Pager pager = getPageManager();
                int page = pager.peekNextPage();
                int pageSize = pager.getPageSize();
                onMore(refreshView, dataView, page, pageSize, mDataSource, mListener);
            }
        });
    }

}
